#include "ET++.ph"
#ifdef __GNUG__
#pragma implementation
#endif

#include "ClassList.h"

#include "Class.h"
#include "ClassItem.h"
#include "Menu.h"
#include "EtPeCmdNo.h"

#include "OrdColl.h"
#include "ObjList.h"
#include "ClassManager.h"
#include "ObjectTable.h"
#include "String.h"


//---- ClassListView ---------------------------------------------------------------

NewMetaImpl(PeClassListView, CollectionView, (TP(classItems), T(hideEmptyClasses), T(showInstCount)));

PeClassListView::PeClassListView(EvtHandler *b, bool count)
									: CollectionView(b, 0, eCVDontStuckToBorder)
{
	hideEmptyClasses= FALSE;
	showInstCount= count;
	LoadClasses();
}

void PeClassListView::LoadClasses()
{
	Iter next(gClassManager->Iterator());
	Class *clp;
	VObject *vop;

	if (showInstCount)
		ObjectTable::UpdateInstCount();

	classItems= new OrdCollection(200);

	while (clp= (Class*) next()) {
		if (!clp->TestFlag(eClassObject))
			continue;
		if (!(hideEmptyClasses && clp->GetInstanceCount() == 0)) {
			if (showInstCount)
				vop= new PeClassItem(cIdNone, clp,
						form("%s (%d)", clp->Name(), clp->GetInstanceCount()));
			else
				vop= new PeClassItem(cIdNone, clp);
			classItems->Add(vop);
		}
	}
	classItems->Sort();
	SetCollection(classItems);
	Update();
}

void PeClassListView::DoSelect(Rectangle r, int)
{
	if (r.IsEmpty())
		return;
	PeClassItem *ci= (PeClassItem*) classItems->At(r.origin.y);
	if (ci == 0)
		return;
	Control(cPeClassList, cPeCLChangedClass, ci->GetClass());
}

void PeClassListView::DoObserve(int, int part, void*, Object *op)
{
	if (part != cPartSenderDied && op == gClassManager) {
		classItems->Empty();
		LoadClasses();
		SelectClass(0);
	}
}

void PeClassListView::ToggleHideEmpty()
{
	hideEmptyClasses= !hideEmptyClasses;
	LoadClasses();
}

bool PeClassListView::SelectClass(Class *cl)
{
	if (cl == 0) {
		ClearSelection();
		return FALSE;
	}
	Rectangle sr;
	PeClassItem *ci= (PeClassItem*) classItems->At(GetSelection().origin.y);
	if (ci && ci->GetClass() == cl)
		return FALSE;
	PeClassItem *clp= 0, searchItem(0, cl);

	int pos= classItems->BinarySearch(&searchItem);
	if (pos != -1)
		clp= (PeClassItem*) classItems->At(pos);
	if (clp) {
		sr= Rectangle(0, pos, 1, 1);
		SetSelection(sr);
		RevealAlign(ItemRect(sr));
	}
	return TRUE;
}

Class *PeClassListView::SelectedClass()
{
	PeClassItem *ci= (PeClassItem*) classItems->At(GetSelection().origin.y);
	if (ci)
		return ci->GetClass();
	return 0;
}
